package view;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.Transparency;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import java.util.ArrayList;
import javax.swing.JPanel;

import model.MarioObject;
import model.Model;

public class Spielfeld extends JPanel{

	
	private static final long serialVersionUID = 1L;
	private BufferedImage background;
	private BufferedImage foreground;
	private BufferedImage rendered;
	//private VolatileImageMaker maker;
	private String image_path;
	private ImageLoader imageLoader;
	private Graphics gr;
	private Mario parent;
	
	
	public Spielfeld(Mario parent){
		this.parent = parent;
		this.setPreferredSize(new Dimension(800,500));
		this.setSize(800,500);
		this.image_path = "/res/picture/";
		this.imageLoader = new ImageLoader(image_path);
		
		this.foreground = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(this.parent.getModel().width, 500, Transparency.TRANSLUCENT);
		this.rendered = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(this.parent.getModel().width, 500, Transparency.TRANSLUCENT);
		this.setVisible(true);
		
	}
	
	
	public void renderBackground(MarioObject[][][] level){
		
		this.background = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(this.parent.getModel().width, 500, Transparency.TRANSLUCENT);
        
	      
	    //Drawing Background <-auslagern nur einmal zeichnen, au�er wird gekillt im gpu speicher
		for(int i=0; i < level[0].length; i++){
			for( int j=0; j < level[0][j].length; j++){
				if(level[0][i][j] == null) continue;
				MarioObject actual = level[0][i][j];
				int x = actual.getX(), y=actual.getY();
	
				if( actual instanceof model.Obstacle){
					switch(actual.getType()){
						case DIRT:
							this.background.getGraphics().drawImage(imageLoader.getImage("dirt"),x, y, this);
							break;
						case DIRT_GRASS:
							this.background.getGraphics().drawImage(imageLoader.getImage("dirt_grass"),x, y, this);
							break;
						case BLOCK:
							this.background.getGraphics().drawImage(imageLoader.getImage("block"),x, y, this);
							break;
						case WATER:
							this.background.getGraphics().drawImage(imageLoader.getImage("water"),x, y, this);
							break;
						default:
							this.background.getGraphics().drawImage(imageLoader.getImage("na"),x, y, this);
					}				
				}
			}
		}
	
	}
	
	
	public void render(){
		
		Model model = this.parent.getModel();
		MarioObject[][][] level = model.getLevel();
		/*if(this.background != null){
			int valCode = background.validate(getGraphicsConfiguration());
			if (valCode == VolatileImage.IMAGE_RESTORED)
			{
				System.out.println("backBuffer - IMAGE_RESTORED"+background.contentsLost());
				renderBackground(level);
			}
			else if (valCode == VolatileImage.IMAGE_INCOMPATIBLE)
			{
				System.out.println("backBuffer - IMAGE_INCOMPATIBLE");
				renderBackground(level);
			}
		}*/
		
		if(this.background == null) this.renderBackground(level);
		
		
		this.gr = this.foreground.getGraphics();
		this.gr.setColor(Color.white);
		this.gr.setPaintMode();
		this.gr.fillRect(0, 0, model.width, 500);
		
		this.gr.drawImage(this.background,0,0,this);

		for(int dim =1; dim<4 ;dim++){
			for(int i=0; i < level[dim].length; i++){
				for( int j=0; j < level[dim][j].length; j++){
					if(level[dim][i][j] == null) continue;
					MarioObject actual = level[dim][i][j];
					int x = actual.getX(), y=actual.getY();
					
					//Spieler
					if(actual instanceof model.Player){
						switch(actual.getType()){
							case PLAYER_SMALL:
								this.foreground.getGraphics().drawImage(imageLoader.getImage("player_small"),x, y, this);
								break;
							case PLAYER_BIG:
								this.foreground.getGraphics().drawImage(imageLoader.getImage("player_big"),x,y, this);
								break;
							default:
								this.foreground.getGraphics().drawImage(imageLoader.getImage("na"),x, y, this);
						}
					}
					//Gegner
					if(actual instanceof model.Enemy){
						switch(actual.getType()){
							case ENEMY1:
								this.foreground.getGraphics().drawImage(imageLoader.getImage("enemy1"),x, y, this);
								break;
							case ENEMY2:
								this.foreground.getGraphics().drawImage(imageLoader.getImage("enemy2"),x, y, this);
								break;
							default:
								this.foreground.getGraphics().drawImage(imageLoader.getImage("na"),x, y, this);
						}
					}
					//Flower
					if(actual instanceof model.Collectable){
						switch(actual.getType()){
							case ITEM_GROWTH:
								this.foreground.getGraphics().drawImage(imageLoader.getImage("item_growth"),x, y, this);
								break;
							case ITEM_SHOOT:
								this.foreground.getGraphics().drawImage(imageLoader.getImage("item_shoot"),x, y, this);
								break;
							case COIN:
								this.foreground.getGraphics().drawImage(imageLoader.getImage("coin"),x, y, this);
								break;
							default:
								this.foreground.getGraphics().drawImage(imageLoader.getImage("na"),x, y, this);
						}
					}
				}		
			}
		}
		
		
		//verschiebe Grafik je nach posistion Mario
		int minWidth = 0;
		int maxWidth = model.width;
		int offset = 0;
		
		int posMario = level[3][1][7].getX();
		this.gr = this.rendered.getGraphics();
		this.gr.setColor(Color.white);
		this.gr.setPaintMode();
		this.gr.fillRect(0, 0, model.width, 500);
		
		if(posMario < 400)
			offset=minWidth;
		else
			offset = posMario-400;
		
		if(offset >= maxWidth-800)
			offset = maxWidth-800; 
		
		this.rendered.getGraphics().drawImage(this.foreground,-offset, 0, this);
		
		
		
	}

	public void paintComponent(Graphics g)
	{
				
		g.drawImage(this.rendered,0,0,this);	

	}
		
}
